/*
 * Created by kopper on 31.01.15 18:49
 * (C) Copyright 2015 kopperek@gmail.com
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 */

package app.android.kopper.foramemo;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import app.android.kopper.foramemo.util.ExportUtil;
import app.android.kopper.foramemo.util.ForaMemoDbHelper;
import app.android.kopper.foramemo.util.LogProxy;
import app.android.kopper.foramemo.util.Word;
import app.android.kopper.foramemo.util.WordGroupDef;

public class MainActivity extends Activity {

    private static final int CHOOSE_WORDS_FILE_REQUEST_CODE= 0x00;
    private static final int CHOOSE_XML_FILE_REQUEST_CODE= 0x01;

    private static final String SELECTED_FILE_KEY="SELECTED_FILE_KEY";

    private ForaMemoDbHelper dbHelper;

    private Button selectWordsFileButton;
    private Button startButton;
    private Button reloadFileButton;
    private Button optionsButton;

    private String wordsFileName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        File storageDirectory=Environment.getExternalStorageDirectory();
        LogProxy.d("storageDirectory: "+storageDirectory);

        dbHelper=new ForaMemoDbHelper(getApplicationContext());

//        dbHelper.getReadableDatabase().delete(ForaMemoDbHelper.FeedEntry.TABLE_NAME,null,null);

        selectWordsFileButton=(Button)findViewById(R.id.selectWordsFileButton);
        reloadFileButton=(Button)findViewById(R.id.reloadFileButton);
        startButton=(Button)findViewById(R.id.startButton);
        optionsButton=(Button)findViewById(R.id.optionsButton);

        selectWordsFileButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                openSelectFileActivity(CHOOSE_WORDS_FILE_REQUEST_CODE);
            }
        });

        reloadFileButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(wordsFileName!=null)
                    setWordsFile(wordsFileName);
            }
        });

        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent cardIntent=new Intent(getApplicationContext(),CardActivity.class);
                startActivity(cardIntent);
            }
        });

        optionsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openOptionsMenu();
            }
        });

        updateButtonsState(false);

        String wordsFileName=getPreferences(Activity.MODE_PRIVATE).getString(SELECTED_FILE_KEY,null);
        if(wordsFileName!=null)
            setWordsFile(wordsFileName);
    }

    private void openSelectFileActivity(int requestCode) {
        //file manager for nook - https://play.google.com/store/apps/details?id=com.topnet999.android.filemanager
        Intent intent=new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        Intent i=Intent.createChooser(intent,"File");
        startActivityForResult(i,requestCode);
    }

    private void updateButtonsState(boolean enabled) {
        reloadFileButton.setEnabled(enabled);
        startButton.setEnabled(enabled);
        optionsButton.setEnabled(enabled);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (data != null) {
                String dataValue = String.valueOf(data.getData());
                LogProxy.i("Selected file: "+dataValue);
                if (dataValue != null) {
                    if(requestCode==CHOOSE_WORDS_FILE_REQUEST_CODE)
                        setWordsFile(dataValue);
                    if(requestCode==CHOOSE_XML_FILE_REQUEST_CODE)
                        performImport(dataValue);
                }
            }
        }
    }

    private void performImport(String fileName) {
        try {
            LogProxy.i("Import: "+fileName);
            ExportUtil.performExport(dbHelper,".backup");
            SQLiteDatabase writableDatabase=dbHelper.getWritableDatabase();
            writableDatabase.beginTransaction();
            writableDatabase.delete(ForaMemoDbHelper.FeedEntry.TABLE_NAME,null,null);
            InputStream is = getContentResolver().openInputStream(Uri.parse(fileName));
            XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
            XmlPullParser myParser = xmlFactoryObject.newPullParser();
            myParser.setInput(is, null);
            for(;;) {
                myParser.next();
                int type = myParser.getEventType();
                if(type==XmlPullParser.END_DOCUMENT)
                    break;
                if(type==XmlPullParser.START_TAG && ForaMemoDbHelper.FeedEntry.TABLE_NAME.equals(myParser.getName())) {
                    Word word=new Word(myParser);
                    word.save(dbHelper);
                }

            }
            is.close();
            writableDatabase.setTransactionSuccessful();
            writableDatabase.endTransaction();
            setWordsFile(wordsFileName);
            Toast.makeText(getApplicationContext(),"File imported",Toast.LENGTH_SHORT).show();
        } catch(Exception e) {
            LogProxy.e("",e);
            Toast.makeText(getApplicationContext(),"!!! "+e.getLocalizedMessage(),Toast.LENGTH_LONG).show();
        }
    }

    private void setWordsFile(String wordsFileName) {
        this.wordsFileName=wordsFileName;
        ((TextView) findViewById(R.id.wordsFileText)).setText(wordsFileName);
        //save for later
        SharedPreferences.Editor preferencesEditor=getPreferences(Activity.MODE_PRIVATE).edit();
        preferencesEditor.putString(SELECTED_FILE_KEY,wordsFileName);
        preferencesEditor.commit();
        try {
            updateDatabase(wordsFileName);
            ((TextView) findViewById(R.id.forTodayText)).setText(String.format(getString(R.string.todo),ForaMemoDbHelper.getStats(dbHelper)));
            ((TextView) findViewById(R.id.numberOfWordsText)).setText(String.format(getString(R.string.number_of_words),WordGroupDef.getAllWords().getCount(dbHelper)));
            updateButtonsState(true);
        } catch (Exception e) {
            updateButtonsState(false);
            LogProxy.e( "", e);
            ((TextView) findViewById(R.id.numberOfWordsText)).setText(e.getLocalizedMessage());
            ((TextView) findViewById(R.id.forTodayText)).setText("");
        }
    }

    /**
     * read xml file and creates/updates database entries
     * @param wordsFileName
     */
    private void updateDatabase(String wordsFileName) throws IOException, XmlPullParserException {
        Set<String> words = readWords(wordsFileName);

        SQLiteDatabase writableDb = dbHelper.getWritableDatabase();
        SQLiteDatabase readableDb = dbHelper.getReadableDatabase();

        writableDb.beginTransaction();
        int inserted = 0;
        int updated = 0;
        int removed=0;
        for (String word : words) {
            Set<Word> set = dbHelper.selectWords(readableDb, ForaMemoDbHelper.FeedEntry.COLUMN_NAME_WORD + "=?",null, word);
            if (set.size() == 0) {
                Word w = new Word(word, new BigDecimal("2.5"), new Date());
                w.save(dbHelper);
                inserted++;
            } else {
                Word w = set.iterator().next();
                if (Boolean.FALSE.equals(w.getEnable())) {
                    w.setEnable(Boolean.TRUE);
                    w.save(dbHelper);
                    updated++;
                }
            }
        }
        Set<Word> toCheckRemoveSet = dbHelper.selectWords(readableDb, ForaMemoDbHelper.FeedEntry.COLUMN_NAME_ENABLE + "=1",null, null);
        LogProxy.d("toCheckRemoveSet: " + toCheckRemoveSet.size());
        for(Word w:toCheckRemoveSet) {
            if(!words.contains(w.getWord())) {
                w.setEnable(Boolean.FALSE);
                w.save(dbHelper); //wylaczamy
                removed++;
            }
        }

        LogProxy.i("Inserted: " + inserted);
        LogProxy.i("Updated: " + updated);
        LogProxy.i("Removed: "+removed);

        writableDb.setTransactionSuccessful();
        writableDb.endTransaction();
    }

    private Set<String> readWords(String wordsFileName) throws XmlPullParserException, IOException {
        InputStream is = getContentResolver().openInputStream(Uri.parse(wordsFileName));
        XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
        XmlPullParser myParser = xmlFactoryObject.newPullParser();
        myParser.setInput(is, null);
        Set<String> words=new HashSet<>();
        boolean inEntry = false;
        for(;;) {
            myParser.next();
            int type = myParser.getEventType();
            if(type==XmlPullParser.END_DOCUMENT)
                break;
            if(type==XmlPullParser.START_TAG && "entry".equals(myParser.getName()))
                inEntry=true;
            if(type==XmlPullParser.TEXT&&inEntry) {
                words.add(myParser.getText());
                inEntry=false;
            }
        }
        is.close();
        return(words);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if(wordsFileName!=null)
            getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Integer type=null;
        int id = item.getItemId();
        if(id == R.id.action_export_schedule)
            try {
                File xmlFile=ExportUtil.performExport(dbHelper, "");
                Toast.makeText(getApplicationContext(),xmlFile.getAbsolutePath()+" created",Toast.LENGTH_SHORT).show();
            } catch(IOException e) {
                LogProxy.e("",e);
                Toast.makeText(getApplicationContext(),"!!! "+e.getLocalizedMessage(),Toast.LENGTH_LONG).show();
            }
        else if(id == R.id.action_was_lazy) {
            Intent wasLazyIntent=new Intent(getApplicationContext(),WasLazyActivity.class);
            startActivity(wasLazyIntent);
        }
        else if(id == R.id.action_import_schedule)
            openSelectFileActivity(CHOOSE_XML_FILE_REQUEST_CODE);
        else if (id == R.id.action_top20_most_recent)
            type=TopActivity.TYPE_MOST_RECENT;
        else if (id == R.id.action_top20_most_difficult)
            type=TopActivity.TYPE_MOST_DIFFICULT;
        else if (id == R.id.action_top20_most_frequent)
            type=TopActivity.TYPE_MOST_FREQUENT;
        else if (id == R.id.action_repetition_schedule)
            type=TopActivity.TYPE_REPETITION_SCHEDULE;
        if(type!=null) {
            Intent topIntent=new Intent(getApplicationContext(),TopActivity.class);
            topIntent.putExtra(TopActivity.KEY_TYPE,type);
            startActivity(topIntent);

        }
        return super.onOptionsItemSelected(item);
    }
}
